using System;
using System.Configuration;
using System.ServiceModel.Configuration;
using Ninject.Core.Activation;
using Ninject.Core.Creation;
using Nvigorate.Common;
using Nvigorate.Common.Reflection;

namespace Nvigorate.WCF
{
    public class ServiceClientProvider : IProvider
    {
        private Tuple<Type, Type> GetContractTypesFromContext(IContext context)
        {
            var contractType = context.GenericArguments[0];
            var targetType = typeof(ServiceClient<>).MakeGenericType(contractType);
            return Tuple.Create(contractType, targetType);
        }

        internal static string GetEndPointForContractType(Type contractType)
        {
            ClientSection clientSection =
                ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;

            var endpoints =
                clientSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;

            foreach (ChannelEndpointElement endpoint in endpoints)
            {
                if (endpoint.Contract.Equals(contractType.FullName) || endpoint.Contract.Equals(contractType.AssemblyQualifiedName))
                    return endpoint.Name;
            }
            return "";
        }

        public object Create(IContext context)
        {
            var types = GetContractTypesFromContext(context);
            return Reflector.CallMethod(types.Value2, "CreateFromConfigruation", GetEndPointForContractType(types.Value1));
        }

        public Type GetImplementationType(IContext context)
        {
            return typeof(ServiceClient<>);
        }

        public bool IsCompatibleWith(IContext context)
        {
            var contractType = context.GenericArguments[0];

            if(contractType.IsInterface)
                return true;

            return false;
        }

        public Type Prototype
        {
            get { return typeof(ServiceClient<>); }
        }
    }
}